#include "gestionClient.h"

int gestionClient(int socket, gThread * gThread)
{
  int intCmd, rcp = 0, continu = 1, rr;
  char msg2;
  fd_set rfds2, rfds2_tot;
  Fichier fichier;
  char * buf = (char*)malloc(sizeof(char));
  char tmpBuf[65536], crlf[3];
  int tmpRcp = 0;
 
  FD_ZERO(&rfds2_tot);
  FD_SET(socket, &rfds2_tot);
  FD_SET(gThread->gFile.sockPair[0], &rfds2_tot);
  FD_ZERO(&rfds2);
  rfds2 = rfds2_tot;
  crlf[0] = '\r';
  crlf[1] = '\n';
  crlf[2] = '\0';

  if(select(FD_SETSIZE, &rfds2, NULL, NULL, NULL) == -1)
    {
      fprintf(stdout, "\n[clt:%d]! Erreur GestionClient : Select failed.\n", socket);
      free(buf);
      return -1;
    }
  if(FD_ISSET(socket, &rfds2))
    {
      intCmd = 0;
      do{
	do{
	  if(recv(socket, &(tmpBuf[tmpRcp]), sizeof(char), 0) <= 0)
	    {
	      fprintf(stdout, "\n[clt:%d]! Erreur GestionClient : recvCommande.\n", socket);
	      free(buf);
	      return 0;
	    }
	  if(tmpBuf[tmpRcp] == 10)
	    {
	      tmpBuf[tmpRcp] = '\n';
	      tmpRcp ++;
	      tmpBuf[tmpRcp] = '\0';
	      break;
	    }
	  tmpRcp ++;
	}while(tmpRcp < 65536);
	if(rcp == 0)
	  {
	    buf = (char*)realloc(buf, sizeof(char) * (tmpRcp + 1));
	  }
	else
	  {
	    buf = realloc(buf, sizeof(char) * (strlen(buf) + 1 + tmpRcp));
	  }
	sprintf(buf, "%s", tmpBuf);
	rcp += tmpRcp;
	if(strchr(buf, crlf[0]) != NULL || strchr(buf, crlf[1]) != NULL)
	  {
	    char *retc;
	    if((retc = strchr(buf, crlf[0])) != NULL)
	      *retc = '\0';
	    if((retc = strchr(buf, crlf[1])) != NULL)
	      *retc = '\0';
	    tmpBuf[tmpRcp+1] = '\0';
	    tmpBuf[tmpRcp] = '\n';
	    continu = 0;
	  }
      }while(continu == 1);
      if(rcp > 4)
	{
	  intCmd = cmd(buf);
	}else
	{
	  intCmd = -1;
	}
      if(intCmd == 1)
	{
	  fprintf(stdout, "\n[clt:%d]> RCPT %s.\n", socket, buf);
	  if(send_concat("RCPT", buf, rcp, socket) == -1)
	    fprintf(stdout, "[Clt:%d]! Erreur send_concat : RCPT LIST.\n", socket);
	  if(SendListeFichier(gThread->pathFile, socket) == -1)
	    fprintf(stdout, "[Clt:%d]! Erreur SendListeFichier : NOT SENT.\n", socket);
	  if(send(socket, "ENDL\n", 5, 0) == -1)
	    fprintf(stdout, "[clt:%d]! Erreur send : ENDL.\n", socket);
	}
      if(intCmd == 2)
	{
	  fprintf(stdout, "\n[clt:%d]> RCPT %s.\n", socket, buf);
	  if(send_concat("RCPT", buf, rcp, socket) == -1)
	    fprintf(stdout, "[clt:%d]! Erreur send_concat : RCPT GETF.\n", socket);
	  fichier.nomFichier = &(buf[5]);
	  fichier.socket = socket;
	  if(FindFichier(gThread->pathFile, fichier.nomFichier) == 0)
	    {
	      fprintf(stdout, "[clt:%d]! Erreur FindFichier : GETF NONE.\n", socket);
	      if(send(socket, "NONE\n", 5, 0) == -1)
		{
		  fprintf(stdout, "[clt:%d]! Erreur send : NONE.\n", socket);
		}
	    }
	  else
	    {
	      rr = ChercherFichier(&(gThread->gFichier), &fichier);
	      if(rr == 0 || rr == 1)
		{
		  if(rr == 1)
		    {
		      fprintf(stdout, "[clt:%d]: GETF ALREADY LOCK.\n", socket);
		    }		  
		  else if(InsererFichier(&(gThread->gFichier), &fichier) == 1)
		    {
		      fprintf(stdout, "[clt:%d]! Erreur InsererFichier : GETF.\n", socket);
		    }
		  if(envoieFichier(gThread->pathFile, fichier.nomFichier, socket) == 1)
		    {
		      fprintf(stdout, "[clt:%d]! Erreur envoieFichier", socket);
		    }
		  else
		    {			    
		      fprintf(stdout, "[clt:%d]: GETF SUCCESS.\n", socket);
		    }
		}
	      else if(rr == 2)
		{
		  if(send(socket, "BUSY\n", 5, 0) == -1)
		    fprintf(stdout, "[clt:%d]! Erreur send : BUSY.\n", socket);
		  fprintf(stdout, "[clt:%d]: GETF BUSY.\n", socket);
		}
	    }
	}
      if(intCmd == 3)
	{
	  fprintf(stdout, "\n[clt:%d]> RCPT %s.\n", socket, buf);
	  if(send_concat("RCPT", buf, rcp, socket) == -1)
	    fprintf(stdout, "[clt:%d]! Erreur send_concat : RCPT FREE.\n", socket);
	  fichier.nomFichier = &(buf[5]);
	  fichier.socket = socket;
	  rr = SupprimerFichier(&(gThread->gFichier), &fichier);
	  if(rr == 0)
	    {
	      fprintf(stdout, "[clt:%d]: FREE NOT LOCKED.\n", socket);
	    }
	  else if(rr == 2)
	    {
	      fprintf(stdout, "[clt:%d]! Erreur SupprimerFichier : FREE FAILED.\n", socket);
	    }
	  else if(rr == 3)
	    {
	      fprintf(stdout, "[clt:%d]: FREE CAN'T UNLOCK.\n", socket);
	    }
	  else
	    {
	      fprintf(stdout, "[clt:%d]: FREE SUCCESS.\n", socket);
	    }
	  if(send(socket, "FREE\n", 5, 0) == -1)
	    fprintf(stdout, "[clt:%d]! Erreur send : FREE.\n", socket);
	}
      if(intCmd == 0)
	{
	  fprintf(stdout, "\n[clt:%d]> RCPT %s.\n", socket, buf);
	  if(send_concat("RCPT", "QUIT", rcp, socket) == -1)
	    fprintf(stdout, "[clt:%d]! Erreur send_concat : RCPT QUIT.\n", socket);
	  if(send(socket, "OLEH\n", 5, 0) == -1)
	    fprintf(stdout, "[clt:%d]! Erreur send : OLEH.\n", socket);
	}
      if(intCmd == -1)
	{
	  /*fprintf(stdout, "\n[clt:%d]> RCPT UNKNOWED COMMAND (%s).\n", socket, buf);*/
	  if(send_concat("RCPT", buf, rcp, socket) == -1)
	    fprintf(stdout, "[clt:%d]! Erreur send_concat : FAIL.\n", socket);
	  if(send(socket, "FAIL\n", 5, 0) == -1)
	    fprintf(stdout, "[clt:%d]! Erreur send : FAIL.\n", socket);
	}
      free(buf);
      return intCmd;
    }
  if(FD_ISSET(gThread->gFile.sockPair[0], &rfds2))
    {
      read(gThread->gFile.sockPair[0], &msg2, sizeof(char));
      if(msg2 == 'Q')
	{
	  free(buf);
	  return 0;
	}
    }
  free(buf);
  return -1;
}
  
int cmd(char* chaine)
{
  int ret = -1;
  if(strncmp(chaine, "LIST", 4) == 0)
    {
      if(strlen(chaine) == 4)
	{
	  ret = 1;
	}
      else
	{
	  ret = -1;
	}
    }
  else if(strncmp(chaine, "GETF", 4) == 0)
    {
      ret = 2;
    }
  else if(strncmp(chaine, "FREE", 4) == 0)
    {
      ret = 3;
    }
  else if(strncmp(chaine, "QUIT", 4) == 0)
    {
      if(strlen(chaine) == 4)
	{
	  ret = 0;
	}
      else
	{
	  ret = -1;
	}
    }
  else
    {
      ret = -1;
    }
  return ret;
}

int send_concat(char prefix[4], char * chaine, int sizeChaine, int socket)
{
  char * concat = (char*)malloc(sizeof(char)*(7+sizeChaine));
  sprintf(concat, "%s %s\n", prefix, chaine);
  if(send(socket, concat, sizeof(char)*(strlen(concat)), 0) == -1)
    {
      fprintf(stdout, "[clt:%d]! Erreur send : RCPT/FAIL.\n", socket);
      free(concat);  
      return -1;
    }
  free(concat);
  return 0;
}
